package cn.itsource.service.impl;

import cn.itsource.Dto.StockDto;
import cn.itsource.Properties.StockThresholdProperties;
import cn.itsource.domain.Product;
import cn.itsource.domain.PurchaseApply;
import cn.itsource.domain.Stock;
import cn.itsource.domain.StockWarningLog;
import cn.itsource.enums.GlobalExceptionCode;
import cn.itsource.exception.GlobalCustomException;
import cn.itsource.feign.ProductService;
import cn.itsource.feign.PurchaseApplyService;
import cn.itsource.mapper.StockMapper;
import cn.itsource.result.JSONResult;
import cn.itsource.service.IStockService;
import cn.itsource.service.IStockWarningLogService;
import cn.itsource.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.hamcrest.core.Is;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author director
 * @since 2022-09-29
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {

    @Autowired
    private ProductService productService;

    @Autowired
    private StockThresholdProperties stockThresholdProperties;

    @Autowired
    private IStockWarningLogService stockWarningLogService;

    @Autowired
    private PurchaseApplyService purchaseApplyService;


    @Override
    public void toso(StockDto stockDto) {
        Stock stock = selectStock(stockDto.getProductId());
        if (stockDto.getStatus() == 0){ // 入库
            if (stock == null){
                empty(stockDto);
            } else {
                stock.setCount(stock.getCount() + stockDto.getCount());
                updateById(stock);
            }
        } else if (stockDto.getStatus() == 1){ // 出库
                Integer count = stock.getCount();
            if (stock.getCount() < stockDto.getCount() ){ //此时库存不足
                // 库存少于阈值时，记录库存警告日志，阈值使用yml进行常量设置
                if (count < stockThresholdProperties.getThreshold()){
                    lThanThreshold(stock);
                } else { // 库存足够
                    enough(stockDto, stock);
                }
            }
        }


    }

    private void empty(StockDto stockDto) {
        Stock stock;
        stock = new Stock();
        stock.setCount(stockDto.getCount());
        stock.setProductId(stockDto.getProductId());
        JSONResult jsonResult = productService.get(stockDto.getProductId());
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCode.ERROR);
        Object data = jsonResult.getData();
        AssertUtil.isNotNull(data,GlobalExceptionCode.ERROR);
        String jsonStr = JSONObject.toJSONString(data);
        Product product = JSON.parseObject(jsonStr, Product.class);
        stock.setProductName(product.getProductName());
        stock.setCreateTime(new Date());
        insert(stock);
    }

    private void enough(StockDto stockDto, Stock stock) {
        stock.setCount(stock.getCount() - stockDto.getCount());
        updateById(stock);
        PurchaseApply purchaseApply = new PurchaseApply();
        BeanUtils.copyProperties(stock,purchaseApply);
        purchaseApply.setCreateTime(new Date());
        purchaseApply.setCount(stockThresholdProperties.getCount());
        purchaseApply.setStatus(0);
        purchaseApplyService.saveOrUpdate(purchaseApply);
        throw new GlobalCustomException(stockThresholdProperties.getFailedToIssue());
    }

    private void lThanThreshold(Stock stock) {
        Date date = new Date();
        StockWarningLog stockWarningLog = new StockWarningLog();
        // BeanUtils.copyProperties方法简单来说就是将两个字段相同的对象进行属性值的复制。
        // 如果两个对象之间存在名称不相同的属性，则 BeanUtils 不对这些属性进行处理，需要程序手动处理。
        BeanUtils.copyProperties(stock,stockWarningLog);
        stockWarningLog.setCreateTime(date);
        stockWarningLog.setInfo(stock.getProductName() + stockThresholdProperties.getInventoryProblems());
        stockWarningLogService.insert(stockWarningLog);
        PurchaseApply purchaseApply = new PurchaseApply();
        BeanUtils.copyProperties(stock,purchaseApply);
        purchaseApply.setCount(stockThresholdProperties.getCount());
        purchaseApply.setStatus(0);
        purchaseApplyService.saveOrUpdate(purchaseApply);
        throw new GlobalCustomException(stockThresholdProperties.getFailedToIssue());
    }

    @Override
    public List<Stock> lack() {
        // 获取库存阈值
        Integer threshold = stockThresholdProperties.getThreshold();
        Wrapper<Stock> Wrapper = new EntityWrapper<>();
        Wrapper.eq("count", threshold);
        return selectList(Wrapper);
    }

    private Stock selectStock(Long productId) {
        Wrapper<Stock> Wrapper = new EntityWrapper();
        Wrapper.lt("product_id", productId);
        return selectOne(Wrapper);
    }
}
